
package com.ebrg.secure9.activity;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;

import com.ebrg.secure9.Account;
import com.ebrg.secure9.AccountStats;
import com.ebrg.secure9.BaseAccount;
import com.ebrg.secure9.FontSizes;
import com.ebrg.secure9.Secure9;
import com.ebrg.secure9.Preferences;
import com.ebrg.secure9.SearchAccount;
import com.ebrg.secure9.SearchSpecification;
import com.ebrg.secure9.activity.setup.AccountSettings;
import com.ebrg.secure9.activity.setup.AccountSetupBasics;
import com.ebrg.secure9.activity.setup.EncryptionSettings;
import com.ebrg.secure9.activity.setup.Prefs;
import com.ebrg.secure9.controller.MessagingController;
import com.ebrg.secure9.controller.MessagingListener;
import com.ebrg.secure9.mail.Flag;
import com.ebrg.secure9.mail.security.Keys;
import com.ebrg.secure9.R;

public class Accounts extends K9ListActivity implements OnItemClickListener, OnClickListener
{
	private static final int DIALOG_REMOVE_ACCOUNT = 1;
	private static final int DIALOG_CLEAR_ACCOUNT = 2;
	private static final int DIALOG_RECREATE_ACCOUNT = 3;
	private ConcurrentHashMap<String, AccountStats> accountStats = new ConcurrentHashMap<String, AccountStats>();

	private ConcurrentHashMap<BaseAccount, String> pendingWork = new ConcurrentHashMap<BaseAccount, String>();

	private BaseAccount mSelectedContextAccount;
	private int mUnreadMessageCount = 0;

	private AccountsHandler mHandler = new AccountsHandler();
	private AccountsAdapter mAdapter;
	private SearchAccount unreadAccount = null;
	private SearchAccount integratedInboxAccount = null;
	private FontSizes mFontSizes = Secure9.getFontSizes();

	//Secure9
	private String accountEmail = null;

	class AccountsHandler extends Handler
	{
		private void setViewTitle()
		{
			String dispString = mListener.formatHeader(Accounts.this, getString(R.string.accounts_title), mUnreadMessageCount, getTimeFormat());

			setTitle(dispString);
		}
		public void refreshTitle()
		{
			runOnUiThread(new Runnable()
			{
				public void run()
				{
					setViewTitle();
				}
			});
		}

		public void dataChanged()
		{
			runOnUiThread(new Runnable()
			{
				public void run()
				{
					if (mAdapter != null)
					{
						mAdapter.notifyDataSetChanged();
					}
				}
			});
		}

		public void workingAccount(final Account account, final int res)
		{
			runOnUiThread(new Runnable()
			{
				public void run()
				{
					String toastText = getString(res, account.getDescription());

					Toast toast = Toast.makeText(getApplication(), toastText, Toast.LENGTH_SHORT);
					toast.show();
				}
			});
		}

		public void accountSizeChanged(final Account account, final long oldSize, final long newSize)
		{
			runOnUiThread(new Runnable()
			{
				public void run()
				{
					AccountStats stats = accountStats.get(account.getUuid());
					if (newSize != -1 && stats != null && Secure9.measureAccounts())
					{
						stats.size = newSize;
					}
					String toastText = getString(R.string.account_size_changed, account.getDescription(),
							SizeFormatter.formatSize(getApplication(), oldSize), SizeFormatter.formatSize(getApplication(), newSize));;

							Toast toast = Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG);
							toast.show();
							if (mAdapter != null)
							{
								mAdapter.notifyDataSetChanged();
							}
				}
			});
		}

		public void progress(final boolean progress)
		{
			runOnUiThread(new Runnable()
			{
				public void run()
				{
					setProgressBarIndeterminateVisibility(progress);
				}
			});
		}
		public void progress(final int progress)
		{
			runOnUiThread(new Runnable()
			{
				public void run()
				{
					getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress);
				}
			});
		}
	}

	ActivityListener mListener = new ActivityListener()
	{
		@Override
		public void folderStatusChanged(Account account, String folderName, int unreadMessageCount)
		{
			try
			{
				AccountStats stats = account.getStats(Accounts.this);
				accountStatusChanged(account, stats);
			}
			catch (Exception e)
			{
				Log.e(Secure9.LOG_TAG, "Unable to get account stats", e);
			}
		}
		@Override
		public void accountStatusChanged(BaseAccount account, AccountStats stats)
		{
			AccountStats oldStats = accountStats.get(account.getUuid());
			int oldUnreadMessageCount = 0;
			if (oldStats != null)
			{
				oldUnreadMessageCount = oldStats.unreadMessageCount;
			}
			accountStats.put(account.getUuid(), stats);
			if (account instanceof Account)
			{
				mUnreadMessageCount += stats.unreadMessageCount - oldUnreadMessageCount;
			}
			mHandler.dataChanged();
			pendingWork.remove(account);

			if (pendingWork.isEmpty())
			{
				mHandler.progress(Window.PROGRESS_END);
				mHandler.refreshTitle();
			}
			else
			{
				int level = (Window.PROGRESS_END / mAdapter.getCount()) * (mAdapter.getCount() - pendingWork.size()) ;
				mHandler.progress(level);
			}
		}

		@Override
		public void accountSizeChanged(Account account, long oldSize, long newSize)
		{
			mHandler.accountSizeChanged(account, oldSize, newSize);
		}

		@Override
		public void synchronizeMailboxFinished(
				Account account,
				String folder,
				int totalMessagesInMailbox,
				int numNewMessages)
		{
			super.synchronizeMailboxFinished(account, folder, totalMessagesInMailbox, numNewMessages);
			MessagingController.getInstance(getApplication()).getAccountStats(Accounts.this, account, mListener);

			mHandler.progress(false);

			mHandler.refreshTitle();
		}

		@Override
		public void synchronizeMailboxStarted(Account account, String folder)
		{
			super.synchronizeMailboxStarted(account, folder);
			mHandler.progress(true);
			mHandler.refreshTitle();
		}

		@Override
		public void synchronizeMailboxProgress(Account account, String folder, int completed, int total)
		{
			super.synchronizeMailboxProgress(account, folder, completed, total);
			mHandler.refreshTitle();
		}

		@Override
		public void synchronizeMailboxFailed(Account account, String folder,
				String message)
		{
			super.synchronizeMailboxFailed(account, folder, message);
			mHandler.progress(false);
			mHandler.refreshTitle();

		}

		@Override
		public void sendPendingMessagesStarted(Account account)
		{
			super.sendPendingMessagesStarted(account);
			mHandler.refreshTitle();
		}

		@Override
		public void sendPendingMessagesCompleted(Account account)
		{
			super.sendPendingMessagesCompleted(account);
			mHandler.refreshTitle();
		}


		@Override
		public void sendPendingMessagesFailed(Account account)
		{
			super.sendPendingMessagesFailed(account);
			mHandler.refreshTitle();
		}

		@Override
		public void pendingCommandsProcessing(Account account)
		{
			super.pendingCommandsProcessing(account);
			mHandler.refreshTitle();
		}

		@Override
		public void pendingCommandsFinished(Account account)
		{
			super.pendingCommandsFinished(account);
			mHandler.refreshTitle();
		}

		@Override
		public void pendingCommandStarted(Account account, String commandTitle)
		{
			super.pendingCommandStarted(account, commandTitle);
			mHandler.refreshTitle();
		}

		@Override
		public void pendingCommandCompleted(Account account, String commandTitle)
		{
			super.pendingCommandCompleted(account, commandTitle);
			mHandler.refreshTitle();
		}


	};

	private static String ACCOUNT_STATS = "accountStats";
	private static String SELECTED_CONTEXT_ACCOUNT = "selectedContextAccount";

	public static final String EXTRA_STARTUP = "startup";


	public static void actionLaunch(Context context)
	{
		Intent intent = new Intent(context, Accounts.class);
		intent.putExtra(EXTRA_STARTUP, true);
		context.startActivity(intent);
	}

	public static void listAccounts(Context context)
	{
		Intent intent = new Intent(context, Accounts.class);
		intent.putExtra(EXTRA_STARTUP, false);
		context.startActivity(intent);
	}


	@Override
	public void onCreate(Bundle icicle)
	{

		
		unreadAccount = new SearchAccount(this, false, null, null);
		unreadAccount.setDescription(getString(R.string.search_all_messages_title));
		unreadAccount.setEmail(getString(R.string.search_all_messages_detail));

		integratedInboxAccount = new SearchAccount(this, true, null,  null);
		integratedInboxAccount.setDescription(getString(R.string.integrated_inbox_title));
		integratedInboxAccount.setEmail(getString(R.string.integrated_inbox_detail));

		super.onCreate(icicle);

		Account[] accounts = Preferences.getPreferences(this).getAccounts();
		Intent intent = getIntent();
		boolean startup = intent.getBooleanExtra(EXTRA_STARTUP, true);
		if (startup && accounts.length == 1)
		{
			onOpenAccount(accounts[0]);
			finish();
		}
		else
		{
			requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
			requestWindowFeature(Window.FEATURE_PROGRESS);

			setContentView(R.layout.accounts);
			ListView listView = getListView();
			listView.setOnItemClickListener(this);
			listView.setItemsCanFocus(false);
			listView.setEmptyView(findViewById(R.id.empty));
			findViewById(R.id.next).setOnClickListener(this);
			registerForContextMenu(listView);

			if (icicle != null && icicle.containsKey(SELECTED_CONTEXT_ACCOUNT))
			{
				String accountUuid = icicle.getString("selectedContextAccount");
				mSelectedContextAccount = Preferences.getPreferences(this).getAccount(accountUuid);
			}

			if (icicle != null)
			{
				Map<String, AccountStats> oldStats = (Map<String, AccountStats>)icicle.get(ACCOUNT_STATS);
				if (oldStats != null)
				{
					accountStats.putAll(oldStats);
				}
			}
		}
	}

	@Override
	public void onSaveInstanceState(Bundle outState)
	{
		super.onSaveInstanceState(outState);
		if (mSelectedContextAccount != null)
		{
			outState.putString(SELECTED_CONTEXT_ACCOUNT, mSelectedContextAccount.getUuid());
		}
		outState.putSerializable(ACCOUNT_STATS, accountStats);
	}

	@Override
	public void onResume()
	{
		super.onResume();

		refresh();
		MessagingController.getInstance(getApplication()).addListener(mListener);
	}

	@Override
	public void onPause()
	{
		super.onPause();
		MessagingController.getInstance(getApplication()).removeListener(mListener);
	}

	private void refresh()
	{
		BaseAccount[] accounts = Preferences.getPreferences(this).getAccounts();

		List<BaseAccount> newAccounts = new ArrayList<BaseAccount>(accounts.length + 4);
		if (accounts.length > 0)
		{
			newAccounts.add(integratedInboxAccount);
			newAccounts.add(unreadAccount);
		}

		for (BaseAccount account : accounts)
		{
			newAccounts.add(account);
		}

		mAdapter = new AccountsAdapter(newAccounts.toArray(new BaseAccount[0]));
		getListView().setAdapter(mAdapter);
		if (newAccounts.size() > 0)
		{
			mHandler.progress(Window.PROGRESS_START);
		}
		pendingWork.clear();

		for (BaseAccount account : newAccounts)
		{

			if (account instanceof Account)
			{
				pendingWork.put(account, "true");
				Account realAccount = (Account)account;
				MessagingController.getInstance(getApplication()).getAccountStats(Accounts.this, realAccount, mListener);
			}
			else if (Secure9.countSearchMessages() && account instanceof SearchAccount)
			{
				pendingWork.put(account, "true");
				final SearchAccount searchAccount = (SearchAccount)account;

				MessagingController.getInstance(getApplication()).searchLocalMessages(searchAccount, null, new MessagingListener()
				{
					@Override
					public void searchStats(AccountStats stats)
					{
						mListener.accountStatusChanged(searchAccount, stats);
					}
				});
			}
		}

	}

	private void onAddNewAccount()
	{
		AccountSetupBasics.actionNewAccount(this);
	}

	private void onEditAccount(Account account)
	{
		AccountSettings.actionSettings(this, account);
	}

	private void onEditPrefs()
	{
		Prefs.actionPrefs(this);
	}

	private void onEditEncrypt(Account account)
	{
		EncryptionSettings.encryptionSettings(this, account);
	}

	/*
	 * This method is called with 'null' for the argument 'account' if
	 * all accounts are to be checked. This is handled accordingly in
	 * MessagingController.checkMail().
	 */
	private void onCheckMail(Account account)
	{
		MessagingController.getInstance(getApplication()).checkMail(this, account, true, true, null);
	}

	private void onClearCommands(Account account)
	{
		MessagingController.getInstance(getApplication()).clearAllPending(account);
	}

	private void onEmptyTrash(Account account)
	{
		MessagingController.getInstance(getApplication()).emptyTrash(account, null);
	}


	private void onCompose()
	{
		Account defaultAccount = Preferences.getPreferences(this).getDefaultAccount();
		if (defaultAccount != null)
		{
			MessageCompose.actionCompose(this, defaultAccount);
		}
		else
		{
			onAddNewAccount();
		}
	}

	private void onOpenAccount(BaseAccount account)
	{
		if (account instanceof SearchAccount)
		{
			SearchAccount searchAccount = (SearchAccount)account;
			MessageList.actionHandle(this, searchAccount.getDescription(), searchAccount);
		}
		else
		{
			Account realAccount = (Account)account;
			if (Secure9.FOLDER_NONE.equals(realAccount.getAutoExpandFolderName()))
			{
				FolderList.actionHandleAccount(this, realAccount);
			}
			else
			{
				MessageList.actionHandleFolder(this, realAccount, realAccount.getAutoExpandFolderName());
			}
		}
	}

	private void showEncryptionBasics(){
		EncryptionBasics.actionLaunch(Accounts.this);
	}
	
	public void onClick(View view)
	{
		if (view.getId() == R.id.next)
		{

			Account[] accounts = Preferences.getPreferences(this).getAccounts();
			if(accounts.length==0)
				showEncryptionBasics();
			else
				onAddNewAccount();
		}
	}

	private void onDeleteAccount(Account account)
	{	

		mSelectedContextAccount = account;
		showDialog(DIALOG_REMOVE_ACCOUNT);
		accountEmail = account.getEmail();


	}

	@Override
	public Dialog onCreateDialog(int id)
	{ 
		switch (id)
		{
		case DIALOG_REMOVE_ACCOUNT:
			return createRemoveAccountDialog();
		case DIALOG_CLEAR_ACCOUNT:
			return createClearAccountDialog();
		case DIALOG_RECREATE_ACCOUNT:
			return createRecreateAccountDialog();
		}
		return super.onCreateDialog(id);
	}

	@Override
	public void onPrepareDialog(int id, Dialog d)
	{
		switch (id)
		{
		case DIALOG_REMOVE_ACCOUNT:
			AlertDialog alert = (AlertDialog) d;
			alert.setMessage(getString(R.string.account_delete_dlg_instructions_fmt,
					mSelectedContextAccount.getDescription()));
			break;
		}

		super.onPrepareDialog(id, d);
	}


	private Dialog createRemoveAccountDialog()
	{
		return new AlertDialog.Builder(this)
		.setTitle(R.string.account_delete_dlg_title)
		.setMessage(getString(R.string.account_delete_dlg_instructions_fmt, mSelectedContextAccount.getDescription()))
		.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{
				dismissDialog(DIALOG_REMOVE_ACCOUNT);

				if (mSelectedContextAccount instanceof Account)
				{
					Account realAccount = (Account)mSelectedContextAccount;
					try
					{
						realAccount.getLocalStore().delete();
					}
					catch (Exception e)
					{
						// Ignore
					}
					
					Keys.refreshKeys(Accounts.this);					
					//keyArray now has all files. Go through and delete all
					//Keys and Pins starting with email address of
					//account being deleted.
					for(int i=0; i<Keys.keyArray.length;i++)
						if(Keys.keyArray[i].startsWith(realAccount.getEmail()))
							Accounts.this.deleteFile(Keys.keyArray[i]);							
					
					Toast.makeText(Accounts.this, "Encryption Keys, initial keys, and PIN deleted", Toast.LENGTH_LONG).show();

					MessagingController.getInstance(getApplication()).notifyAccountCancel(Accounts.this, realAccount);
					Preferences.getPreferences(Accounts.this).deleteAccount(realAccount);
					Secure9.setServicesEnabled(Accounts.this);
					refresh();
				}
			}
		})
		.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{
				dismissDialog(DIALOG_REMOVE_ACCOUNT);
			}
		})
		.create();
	}

	private Dialog createClearAccountDialog()
	{
		return new AlertDialog.Builder(this)
		.setTitle(R.string.account_clear_dlg_title)
		.setMessage(getString(R.string.account_clear_dlg_instructions_fmt, mSelectedContextAccount.getDescription()))
		.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{
				dismissDialog(DIALOG_CLEAR_ACCOUNT);

				if (mSelectedContextAccount instanceof Account)
				{
					Account realAccount = (Account)mSelectedContextAccount;
					mHandler.workingAccount(realAccount, R.string.clearing_account);
					MessagingController.getInstance(getApplication()).clear(realAccount, null);
				}
			}
		})
		.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{
				dismissDialog(DIALOG_CLEAR_ACCOUNT);
			}
		})
		.create();
	}

	private Dialog createRecreateAccountDialog()
	{
		return new AlertDialog.Builder(this)
		.setTitle(R.string.account_recreate_dlg_title)
		.setMessage(getString(R.string.account_recreate_dlg_instructions_fmt, mSelectedContextAccount.getDescription()))
		.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{
				dismissDialog(DIALOG_RECREATE_ACCOUNT);

				if (mSelectedContextAccount instanceof Account)
				{
					Account realAccount = (Account)mSelectedContextAccount;
					mHandler.workingAccount(realAccount, R.string.recreating_account);
					MessagingController.getInstance(getApplication()).recreate(realAccount, null);
				}
			}
		})
		.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{
				dismissDialog(DIALOG_RECREATE_ACCOUNT);
			}
		})
		.create();
	}

	@Override
	public boolean onContextItemSelected(MenuItem item)
	{
		AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo)item.getMenuInfo();
		// submenus don't actually set the menuInfo, so the "advanced"
		// submenu wouldn't work.
		if (menuInfo != null)
		{
			mSelectedContextAccount = (BaseAccount)getListView().getItemAtPosition(menuInfo.position);
		}
		Account realAccount = null;
		if (mSelectedContextAccount instanceof Account)
		{
			realAccount = (Account)mSelectedContextAccount;
		}
		switch (item.getItemId())
		{
		case R.id.delete_account:
			onDeleteAccount(realAccount);
			break;
		case R.id.edit_account:
			onEditAccount(realAccount);
			break;
		case R.id.open:
			onOpenAccount(mSelectedContextAccount);
			break;
		case R.id.check_mail:
			onCheckMail(realAccount);
			break;
		case R.id.clear_pending:
			onClearCommands(realAccount);
			break;
		case R.id.empty_trash:
			onEmptyTrash(realAccount);
			break;
		case R.id.compact:
			onCompact(realAccount);
			break;
		case R.id.clear:
			onClear(realAccount);
			break;
		case R.id.recreate:
			onRecreate(realAccount);
			break;
		}
		return true;
	}



	private void onCompact(Account account)
	{
		mHandler.workingAccount(account, R.string.compacting_account);
		MessagingController.getInstance(getApplication()).compact(account, null);
	}

	private void onClear(Account account)
	{
		showDialog(DIALOG_CLEAR_ACCOUNT);

	}
	private void onRecreate(Account account)
	{
		showDialog(DIALOG_RECREATE_ACCOUNT);
	}


	public void onItemClick(AdapterView<?> parent, View view, int position, long id)
	{
		BaseAccount account = (BaseAccount)parent.getItemAtPosition(position);
		onOpenAccount(account);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
		case R.id.add_new_account:
			onAddNewAccount();
			break;
		case R.id.edit_prefs:
			onEditPrefs();
			break;
		case R.id.check_mail:
			onCheckMail(null);
			break;
		case R.id.compose:
			onCompose();
			break;
		case R.id.about:
			onAbout();
			break;
		case R.id.search:
			onSearchRequested();
			break;
		default:
			return super.onOptionsItemSelected(item);
		}
		return true;
	}

	private void onAbout()
	{
		String appName = getString(R.string.beta_app_name);
		WebView wv = new WebView(this);
		String html = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />" +
		"<h1>" + String.format(getString(R.string.about_title_fmt),
				"<a href=\"" + getString(R.string.app_webpage_url) + "\">" + appName + "</a>") + "</h1>" +
				"<p>" + appName + " " +
				String.format(getString(R.string.debug_version_fmt),
						getVersionNumber()) + "</p>" +
						"<p>" + String.format(getString(R.string.app_authors_fmt),
								getString(R.string.app_authors)) + "</p>" +
									String.format(getString(R.string.eula),
											getString(R.string.eula)) + "</p>" +
											"<p>" + String.format(getString(R.string.app_revision_fmt),
													"<a href=\"" + getString(R.string.app_revision_url) + "\">" +
													getString(R.string.app_revision_url) + "</a></p>");
		wv.loadData(html, "text/html", "utf-8");
		new AlertDialog.Builder(this)
		.setView(wv)
		.setCancelable(true)
		.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface d, int c)
			{
				d.dismiss();
			}
		})
		.show();
	}

	/**
	 * Get current version number.
	 *
	 * @return String version
	 */
	private String getVersionNumber()
	{
		String version = "?";
		try
		{
			PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
			version = pi.versionName;
		}
		catch (PackageManager.NameNotFoundException e)
		{
			//Log.e(TAG, "Package name not found", e);
		};
		return version;
	}

	public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
	{
		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		super.onCreateOptionsMenu(menu);
		getMenuInflater().inflate(R.menu.accounts_option, menu);
		return true;
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
	{
		super.onCreateContextMenu(menu, v, menuInfo);
		menu.setHeaderTitle(R.string.accounts_context_menu_title);
		getMenuInflater().inflate(R.menu.accounts_context, menu);

		AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
		BaseAccount account =  mAdapter.getItem(info.position);
		if (account instanceof SearchAccount)
		{
			for (int i = 0; i < menu.size(); i++)
			{
				MenuItem item = menu.getItem(i);
				if (item.getItemId() != R.id.open)
				{
					item.setVisible(false);
				}
			}
		}
	}

	class AccountsAdapter extends ArrayAdapter<BaseAccount>
	{
		public AccountsAdapter(BaseAccount[] accounts)
		{
			super(Accounts.this, 0, accounts);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent)
		{
			final BaseAccount account = getItem(position);
			View view;
			if (convertView != null)
			{
				view = convertView;
			}
			else
			{
				view = getLayoutInflater().inflate(R.layout.accounts_item, parent, false);
			}
			AccountViewHolder holder = (AccountViewHolder) view.getTag();
			if (holder == null)
			{
				holder = new AccountViewHolder();
				holder.description = (TextView) view.findViewById(R.id.description);
				holder.email = (TextView) view.findViewById(R.id.email);
				holder.newMessageCount = (TextView) view.findViewById(R.id.new_message_count);
				holder.flaggedMessageCount = (TextView) view.findViewById(R.id.flagged_message_count);
				holder.activeIcons = (RelativeLayout) view.findViewById(R.id.active_icons);

				holder.chip = view.findViewById(R.id.chip);
				holder.folders = (ImageButton) view.findViewById(R.id.folders);

				view.setTag(holder);
			}
			AccountStats stats = accountStats.get(account.getUuid());

			if (stats != null && account instanceof Account && stats.size >= 0)
			{
				holder.email.setText(SizeFormatter.formatSize(Accounts.this, stats.size));
				holder.email.setVisibility(View.VISIBLE);
			}
			else
			{
				if (account.getEmail().equals(account.getDescription()))
				{
					holder.email.setVisibility(View.GONE);
				}
				else
				{
					holder.email.setVisibility(View.VISIBLE);
					holder.email.setText(account.getEmail());
				}
			}

			String description = account.getDescription();
			if (description == null || description.length() == 0)
			{
				description = account.getEmail();
			}

			holder.description.setText(description);

			Integer unreadMessageCount = null;
			if (stats != null)
			{
				unreadMessageCount = stats.unreadMessageCount;
				holder.newMessageCount.setText(Integer.toString(unreadMessageCount));
				holder.newMessageCount.setVisibility(unreadMessageCount > 0 ? View.VISIBLE : View.GONE);

				holder.flaggedMessageCount.setText(Integer.toString(stats.flaggedMessageCount));
				holder.flaggedMessageCount.setVisibility(Secure9.messageListStars() && stats.flaggedMessageCount > 0 ? View.VISIBLE : View.GONE);

				holder.flaggedMessageCount.setOnClickListener(new AccountClickListener(account, SearchModifier.FLAGGED));
				holder.newMessageCount.setOnClickListener(new AccountClickListener(account, SearchModifier.UNREAD));

				holder.activeIcons.setOnClickListener(new OnClickListener()
				{
					public void onClick(View v)
					{
						Toast toast = Toast.makeText(getApplication(), getString(R.string.tap_hint), Toast.LENGTH_SHORT);
						toast.show();
					}
				}
				);

			}
			else
			{
				holder.newMessageCount.setVisibility(View.GONE);
				holder.flaggedMessageCount.setVisibility(View.GONE);
			}
			if (account instanceof Account)
			{
				Account realAccount = (Account)account;

				holder.chip.setBackgroundColor(realAccount.getChipColor());
				if (unreadMessageCount == null)
				{
					holder.chip.getBackground().setAlpha(0);
				}
				else if (unreadMessageCount == 0)
				{
					holder.chip.getBackground().setAlpha(127);
				}
				else
				{
					holder.chip.getBackground().setAlpha(255);
				}

			}
			else
			{
				holder.chip.setBackgroundColor(0x00000000);
			}


			holder.description.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getAccountName());
			holder.email.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getAccountDescription());


			if (account instanceof SearchAccount)
			{

				holder.folders.setVisibility(View.GONE);
			}
			else
			{
				holder.folders.setVisibility(View.VISIBLE);
				holder.folders.setOnClickListener(new OnClickListener()
				{
					public void onClick(View v)
					{
						FolderList.actionHandleAccount(Accounts.this, (Account)account);

					}
				});
			}

			return view;
		}

		class AccountViewHolder
		{
			public TextView description;
			public TextView email;
			public TextView newMessageCount;
			public TextView flaggedMessageCount;
			public RelativeLayout activeIcons;
			public View chip;
			public ImageButton folders;
		}
	}
	private Flag[] combine(Flag[] set1, Flag[] set2)
	{
		if (set1 == null)
		{
			return set2;
		}
		if (set2 == null)
		{
			return set1;
		}
		Set<Flag> flags = new HashSet<Flag>();
		for (Flag flag : set1)
		{
			flags.add(flag);
		}
		for (Flag flag : set2)
		{
			flags.add(flag);
		}
		return flags.toArray(new Flag[0]);
	}

	private class AccountClickListener implements OnClickListener
	{

		final BaseAccount account;
		final SearchModifier searchModifier;
		AccountClickListener(BaseAccount nAccount, SearchModifier nSearchModifier)
		{
			account = nAccount;
			searchModifier = nSearchModifier;
		}
		//@Override
		public void onClick(View v)
		{
			String description = getString(R.string.search_title, account.getDescription(), getString(searchModifier.resId));
			if (account instanceof SearchAccount)
			{
				SearchAccount searchAccount = (SearchAccount)account;

				MessageList.actionHandle(Accounts.this,
						description, "", searchAccount.isIntegrate(),
						combine(searchAccount.getRequiredFlags(), searchModifier.requiredFlags),
						combine(searchAccount.getForbiddenFlags(), searchModifier.forbiddenFlags));
			}
			else
			{
				SearchSpecification searchSpec = new SearchSpecification()
				{
					//@Override
					public String[] getAccountUuids()
					{
						return new String[] { account.getUuid() };
					}

					//@Override
					public Flag[] getForbiddenFlags()
					{
						return searchModifier.forbiddenFlags;
					}

					//@Override
					public String getQuery()
					{
						return "";
					}

					//@Override
					public Flag[] getRequiredFlags()
					{
						return searchModifier.requiredFlags;
					}

					//@Override
					public boolean isIntegrate()
					{
						return false;
					}

					//@Override
					public String[] getFolderNames()
					{
						return null;
					}

					public String getEmail() {
						// TODO Auto-generated method stub
						return null;
					}

					public void setEmail(String email) {
						// TODO Auto-generated method stub

					}

				};
				MessageList.actionHandle(Accounts.this, description, searchSpec);
			}
		}

	}

}
